package com.robusta.spreadsheet.model.impl;

import com.robusta.spreadsheet.model.*;
import com.robusta.spreadsheet.model.exception.WorkbookException;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.Iterator;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.newArrayList;
import static com.robusta.spreadsheet.model.impl.RobustaWorkbookFactory.newRow;
import static com.robusta.spreadsheet.model.impl.RobustaWorkbookFactory.newSheetHeaders;

/**
 */
public class RobustaWorksheet implements Worksheet {
    private Sheet sheet;
    private WorksheetTemplate template;
    private SheetHeaders sheetHeaders;
    private List<Row> rows = newArrayList();
    private Workbook parent;

    protected RobustaWorksheet(Workbook parent, Sheet sheet, WorksheetTemplate template) throws WorkbookException {
        this.parent = parent;
        this.sheet = sheet;
        this.template = template;
        initializeSheetHeaders();
        initializeRows();
    }

    private void initializeRows() throws WorkbookException {
        for (int position = template.getHeaderRowIndex() + 1; position < sheet.getLastRowNum(); position++) {
            rows.add(newRow(this, sheet.getRow(position), sheetHeaders, template));
        }
    }

    private void initializeSheetHeaders() {
        sheetHeaders = newSheetHeaders(sheet.getRow(template.getHeaderRowIndex()), template);
    }

    @Override
    public SheetHeaders getHeaders() {
        return sheetHeaders;
    }

    @Override
    public Row getRowAt(int rowIndex) {
        checkArgument(rowIndex >= template.getHeaderRowIndex() + 1 && rowIndex < sheet.getLastRowNum(), String.format("This sheet does not have a row defined at row index: %s", rowIndex));
        return computeRelativeIndexAndGetRowFromList(rowIndex);
    }

    private Row computeRelativeIndexAndGetRowFromList(int rowIndex) {
        return rows.get(rowIndex - template.getHeaderRowIndex() + 1);
    }

    @Override
    public Iterator<Row> iterator() {
        return rows.iterator();
    }

    @Override
    public Workbook owner() {
        return parent;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("RobustaWorksheet");
        sb.append("{template=").append(template);
        sb.append(", sheetHeaders=").append(sheetHeaders);
        sb.append(", rows=").append(rows);
        sb.append('}');
        return sb.toString();
    }
}
